package controller

import (
	"errors"
	"net/http"
	"strconv"
	"time"

	"github.com/kataras/iris"
	"github.com/kataras/iris/sessions"

	"im/common"
	"im/dao"
	"im/errcode"
	"im/model"
	"im/requests"
	"im/responses"
	"im/service"
)

type GroupsController struct {
	Session *sessions.Session
	Ctx     iris.Context
	Base
}

// swagger:route GET /groups/{id}/posts groups get-groups-by-id-posts
//
// 获取群组的帖子列表(小黑板)
//
// 获取该群组所有的帖子列表, id是群组的id
//
//   Security:
//   - jwt_key:
//   Responses:
//     200:GetPosts
func (c *GroupsController) GetByPosts(id int64) {
	var user = c.Ctx.Values().Get("user").(model.Users)
	var param = requests.GetByGroupsPosts{
		Pagination: requests.Pagination{
			Page:  1,
			Limit: 10,
		},
	}
	_ = c.Ctx.ReadQuery(&param)
	err := service.Validate.Struct(&param)
	if err != nil {
		c.SendCry(err)
		return
	}
	if !service.NewGroupUsersService().IsUserInChatGroup(user.Id, id) {
		c.SendCry(errcode.NewError(errcode.UnauthorizedOperation))
		return
	}
	list, err := dao.NewPostsWithEs().GetByGroupId(id, param.Location, param.Pagination)
	if err != nil {
		c.SendCry(err)
		return
	}
	if list == nil {
		list = []dao.PostsWithDistance{}
	}
	c.SendSmile(list)
}

// swagger:route GET /groups groups get-groups
//
// 获取本用户加入的群组列表
//
// 获取群组列表
//
//   Security:
//   - jwt_key:
//   Responses:
//     200:GetGroups
func (c *GroupsController) Get() {
	var (
		user = c.Ctx.Values().Get("user").(model.Users)
		list = &[]model.Groups{}

		err error
	)

	list, err = dao.NewGroupsUsersDao().GetListByUserId(user.Id)
	if err != nil {
		goto SQL_ERR
	}
	c.SendSmile(list)
	return

SQL_ERR:
	c.Ctx.StatusCode(http.StatusInternalServerError)
	c.Ctx.JSON(common.SendSad("服务器发生错误 " + err.Error()))
	return
}

// swagger:route GET /groups/recommend groups get-groups-recommend
//
// 获取群组推荐列表
//
// 获取群组推荐列表
//
//   Security:
//   - jwt_key:
//   Responses:
//     200:GetGroups
func (c *GroupsController) GetRecommend() {
	var param = requests.GetRecommendGroups{
		Pagination: requests.Pagination{
			Page:  1,
			Limit: 10,
		},
	}

	_ = c.Ctx.ReadQuery(&param)
	err := service.Validate.Struct(param)
	if err != nil {
		c.SendCry(err)
		return
	}
	var user = c.Ctx.Values().Get("user").(model.Users)
	list, err := dao.NewGroupsUsersDao().GetRecommendGroups(user, param)
	if err != nil {
		c.SendCry(err)
		return
	}
	c.SendSmile(list)
}

// swagger:route POST /groups groups post-groups
//
// 创建群聊
//
// 创建群聊
//
//   Security:
//   - jwt_key:
//   Responses:
//     200:PostGroups
func (c *GroupsController) Post() {
	var (
		param        = model.GroupsCreatable{}
		user         model.Users
		groupService = service.NewGroupService()

		err error
	)

	_ = c.Ctx.ReadJSON(&param)
	err = service.Validate.Struct(&param)
	if err != nil {
		c.SendCry(err)
		return
	}

	user = c.Ctx.Values().Get("user").(model.Users)
	group, err := groupService.Create(user, param)
	if err != nil {
		c.SendCry(err)
		return
	}
	c.SendSmile(group.Id)
}

// swagger:route DELETE /groups/{id} groups delete-groups
//
// 解散群聊
//
// 解散群聊
//
//   Security:
//   - jwt_key:
//   Responses:
//     200:EmptyResponse
func (c *GroupsController) DeleteBy(id int64) {
	var (
		user         model.Users
		groupService = service.NewGroupService()
		err          error
	)

	user = c.Ctx.Values().Get("user").(model.Users)

	err = groupService.DeleteByID(user.AppsId, id, user)
	if err != nil {
		goto SQL_ERR
	}
	_, err = service.NewGroupUsersService().DeleteByGroupId(user.AppsId, id)
	if err != nil {
		c.SendCry(err)
		return
	}
	c.SendSmile(1)
	return

SQL_ERR:
	c.Ctx.StatusCode(http.StatusInternalServerError)
	c.Ctx.JSON(common.SendSad("服务器发生错误 " + err.Error()))
	return

}

// swagger:route PUT /groups/{id} groups put-groups
//
// 更新群聊信息
//
// 更新群聊信息,支持更新群聊的名字, 描述, 还有最大人数,状态
// 这个只能管理员可以修改
//
//   Security:
//   - jwt_key:
//   Responses:
//     200:EmptyResponse
func (c *GroupsController) PutBy(groupId int64) {
	var (
		user         model.Users
		groupService = service.NewGroupService()
		param        = model.GroupsCreatable{}
		err          error
	)

	user = c.Ctx.Values().Get("user").(model.Users)
	if !dao.NewGroupsUsersDao().IsManager(user.AppsId, groupId, user.Id) {
		c.SendCry(errcode.UnauthorizedOperation)
		return
	}

	_ = c.Ctx.ReadJSON(&param)
	err = groupService.UpdateById(groupId, param)
	if err != nil {
		c.SendCry(err)
		return
	}
	c.SendSmile(1)
	return
}

// swagger:route GET /groups/{id}/messages groups get-groups-messages-by-id
//
// 获取聊天记录
//
// 获取某个群的聊天记录, 可以使用begin_time等过滤
//   Deprecated: true
//   Security:
//   - jwt_key:
//   Responses:
//     200:GetGroupsMessages
func (c *GroupsController) GetByMessages(id int64) {
	var (
		user     = c.Ctx.Values().Get("user").(model.Users)
		response = responses.GetGroupsMessages{}
		param    = requests.GetMessages{}
		err      error
	)
	_ = c.Ctx.ReadQuery(&param)
	response, err = service.NewGroupsMessagesService().GetList(user.AppsId, int64(id), param)
	if err != nil {
		c.SendCry(err)
		return
	}
	c.SendSmile(response)
	return
}

// swagger:route GET /groups/{id}/users groups get-groups-by-users
//
// 获取群成员
//
// 获取群成员
//
//   Security:
//   - jwt_key:
//   Responses:
//     200:GetGroupsByUsers
func (c *GroupsController) GetByUsers(id int64) {
	var user = c.Ctx.Values().Get("user").(model.Users)
	if !service.NewGroupUsersService().IsUserInChatGroup(user.Id, id) {
		c.SendCry(errcode.NewError(errcode.UnauthorizedOperation))
		return
	}
	groupUsers, err := service.NewGroupUsersService().GetListByGroupId(id)
	if err != nil {
		c.SendCry(err)
		return
	}
	c.SendSmile(groupUsers)
}

// swagger:route POST /groups/{id}/users groups post-groups-by-users
//
// 添加用户到群聊
//
// 如果是管理员,可以添加别人, 否则只能添加自己
//
//   Security:
//   - jwt_key:
//   Responses:
//     200:EmptyResponse
func (c *GroupsController) PostByUsers(id int64) {
	var (
		user         = c.Ctx.Values().Get("user").(model.Users)
		params       = requests.PostGroupsByUsers{}
		usersService = service.NewGroupUsersService()
		data         = new(model.GroupsUsers)
		err          error
		toAddUserId  int64
		toAddUser model.Users

	)
	_ = c.Ctx.ReadJSON(&params)
	toAddUserId = common.StringToInt64(params.UserId)
	if toAddUserId == 0 {
		toAddUserId = user.Id
		toAddUser = user
	}else{
		toAddUser, err = service.NewUserService().GetInfoById(toAddUserId)
		if err != nil {
			c.SendCry(err)
			return
		}
	}

	// 确认房间以及归属权
	// if !dao.NewGroupsUsersDao().IsManager(user.AppsId, id, user.Id) && toAddUserId != user.Id {
	// 	err = errcode.NewError(errcode.UnauthorizedOperation)
	// 	c.SendCry(err)
	// 	return
	// }

	data = &model.GroupsUsers{UserId: toAddUserId, AppsId: user.AppsId, GroupId: id, Role: model.GROUP_USER_ROLE_IS_MEMBER,
		Status: 1, Joined: time.Now(), GroupsUsersModifiable: model.GroupsUsersModifiable{
			PostsNotify: 1,
			Nickname:    toAddUser.Nickname,
		}}
	err = usersService.Create(data)
	if err != nil {
		c.SendCry(err)
		return
	}
	groupInfo, err := service.NewGroupService().GetById(id)
	if err != nil {
		c.SendCry(err)
		return
	}
	err = service.NewRongYun().JoinGroup(id, groupInfo.Name, strconv.FormatInt(user.Id, 10))
	if err != nil {
		c.SendCry(err)
		return
	}
	c.SendSmile(toAddUserId)
	return
}

// swagger:route DELETE /groups/{groupId}/users/{userId} groups delete-groups-by-users-by
//
// 退出群聊/踢出群聊
//
// 如果操作用户是管理员,那么是踢出,如果操作用户是用户本身,则自动退出群聊
//
//   Security:
//   - jwt_key:
//   Responses:
//     200: EmptyResponse

func (c *GroupsController) DeleteByUsersBy(groupId int64, userId int64) {
	var (
		user         = c.Ctx.Values().Get("user").(model.Users)
		usersService = service.NewGroupUsersService()
		err          error
	)
	// 确认房间以及归属权
	if !dao.NewGroupsUsersDao().IsManager(user.AppsId, int64(groupId), user.Id) || int64(userId) != user.Id {
		err = errors.New("非法操作")
	}

	_, err = usersService.DeleteByID(user.AppsId, groupId, userId)
	if err != nil {
		c.SendCry(err)
		return
	}
	quitUserInfo := dao.NewUsersDao().Info(userId)
	err = service.NewRongYun().QuitGroup(groupId, strconv.FormatInt(quitUserInfo.Id, 10))
	if err != nil {
		c.SendCry(err)
		return
	}
	c.SendSmile(nil)
	return
}

// swagger:route PUT /groups/{id}/users groups put-groups-by-users
//
// 更新群昵称和帖子通知
//
// 如果操作用户是管理员,那么是踢出,如果操作用户是用户本身,则自动退出群聊
//
//   Security:
//   - jwt_key:
//   Responses:
//     200: EmptyResponse
func (c *GroupsController) PutByUsers(id int64) {
	var user = c.Ctx.Values().Get("user").(model.Users)
	var param = model.GroupsUsersModifiable{}
	_ = c.Ctx.ReadJSON(&param)
	err := service.NewGroupUsersService().Modify(user.Id, param)
	if err != nil {
		c.SendCry(err)
		return
	}
	c.SendSmile(nil)
}
